package zerox

import (
	"errors"
	"github.com/zeromicro/go-zero/core/logx"
	"github.com/zeromicro/go-zero/rest/httpx"
	"net/http"
	"sync"
)

var errCodes = map[int]string{}
var one sync.Once

type Body struct {
	Code int         `json:"code"`
	Msg  string      `json:"msg"`
	Data interface{} `json:"data,omitempty"`
}

type ErrorCode struct {
	Code int    `json:"code"`
	Msg  string `json:"msg"`
}

func (e *ErrorCode) Error() string {
	return e.Msg
}

func Response(w http.ResponseWriter, resp interface{}, err error) {
	var body Body
	if err != nil {
		var e *ErrorCode
		switch {
		case errors.As(err, &e):
			body.Code = e.Code
		default:
			body.Code = 0
		}

		body.Msg = err.Error()
		logx.Error(err)
	} else {
		body.Code = 200
		body.Msg = "OK"
		body.Data = resp
	}
	httpx.OkJson(w, body)
}

func NewErrorCode(code int, err error) *ErrorCode {
	return &ErrorCode{
		Code: code,
		Msg:  err.Error(),
	}
}

func InitErrorCodes(codes map[int]string) {
	one.Do(func() {
		errCodes = codes
	})
}

func Code(code int) *ErrorCode {
	msg, ok := errCodes[code]
	if ok {
		return NewErrorCode(code, errors.New(msg))
	}
	return NewErrorCode(code, errors.New("发生未知错误"))
}
